package kr.co.bnsmedia.touchconfig;

import java.nio.IntBuffer;
import java.util.Arrays;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

public class SideviewView extends View {

	private static final int SIDEVIEW_BITMAP_WIDTH = g.SIDEVIEW_IMAGE_WIDTH;
	private static final int SIDEVIEW_BITMAP_HEIGHT = 4*g.SIDEVIEW_IMAGE_HEIGHT;	// h,h,h,0
	private static final int SIDEVIEW_BITMAP_SIZE = SIDEVIEW_BITMAP_WIDTH * SIDEVIEW_BITMAP_HEIGHT;

	private static final int SIDEVIEW_SCALE = 1;

	private static final int SIDEVIEW_MARGIN = 2;
	private static final int SIDEVIEW_WIDTH = SIDEVIEW_SCALE*3*SIDEVIEW_BITMAP_WIDTH;
	private static final int SIDEVIEW_HEIGHT = SIDEVIEW_SCALE*2*SIDEVIEW_BITMAP_HEIGHT;

	private int mThreshold = 20;

	private int[] mLineZero = new int[SIDEVIEW_BITMAP_WIDTH];
	private int[] mBitmapData = new int[SIDEVIEW_BITMAP_SIZE];
	private Bitmap mBitmap = null;

	private Rect mRectSideview = null;
	private Paint mPaint = null;
	private Paint mPaintRed = null;

	public SideviewView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		init();
	}

	public SideviewView(Context context, AttributeSet attrs) {
		super(context, attrs);

		init();
	}

	public SideviewView(Context context) {
		super(context);

		init();
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int width = SIDEVIEW_WIDTH+2*SIDEVIEW_MARGIN, height = SIDEVIEW_HEIGHT+2*SIDEVIEW_MARGIN;

		switch (widthMeasureSpec) {
		case MeasureSpec.AT_MOST:
			width = Math.min(MeasureSpec.getSize(widthMeasureSpec), width);
			break;
		case MeasureSpec.EXACTLY:
			width = MeasureSpec.getSize(widthMeasureSpec);
			break;
		}

		switch (heightMeasureSpec) {
		case MeasureSpec.AT_MOST:
			height = Math.min(MeasureSpec.getSize(heightMeasureSpec), height);
			break;
		case MeasureSpec.EXACTLY:
			height = MeasureSpec.getSize(heightMeasureSpec);
			break;
		}

		setMeasuredDimension(width, height);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		canvas.drawRect(mRectSideview, mPaint);

		if (null != mBitmap) {
			canvas.drawBitmap(mBitmap, SIDEVIEW_MARGIN, SIDEVIEW_MARGIN, mPaint);

			float yPos = SIDEVIEW_MARGIN+(12*4*2);
			canvas.drawLine(SIDEVIEW_MARGIN, yPos, SIDEVIEW_MARGIN+SIDEVIEW_WIDTH, yPos, mPaintRed);
			yPos = SIDEVIEW_MARGIN+(13*4*2);
			canvas.drawLine(SIDEVIEW_MARGIN, yPos, SIDEVIEW_MARGIN+SIDEVIEW_WIDTH, yPos, mPaintRed);
		}
	}

	public int threshold() {
		return mThreshold;
	}

	public void setThreshold(int threshold) {
		mThreshold = threshold;
	}

	public void reset() {
	}

	public void setData(int aDev, int aDlen, byte[] aData) {
		if (g.SIDEVIEW_IMAGE_SIZE == aDlen) {
			for (int i=0, dataCount=0; i<g.SIDEVIEW_IMAGE_SIZE; i++) {
				int data = (aData[i] & 0xFF);
				if (mThreshold > data) {
					data = 0;
				}

				//((r << 0) | (g << 8) | (b << 16) | (a << 24));
				mBitmapData[dataCount++] = ((data << 0) | (data << 8) | (data << 16) | (0xFF << 24));
				if (0 == (dataCount % SIDEVIEW_BITMAP_WIDTH)) {
					System.arraycopy(mBitmapData, (dataCount-SIDEVIEW_BITMAP_WIDTH), mBitmapData, dataCount, SIDEVIEW_BITMAP_WIDTH);
					dataCount += SIDEVIEW_BITMAP_WIDTH;
					System.arraycopy(mBitmapData, (dataCount-SIDEVIEW_BITMAP_WIDTH), mBitmapData, dataCount, SIDEVIEW_BITMAP_WIDTH);
					dataCount += SIDEVIEW_BITMAP_WIDTH;
					System.arraycopy(mLineZero, 0, mBitmapData, dataCount, SIDEVIEW_BITMAP_WIDTH);
					dataCount += SIDEVIEW_BITMAP_WIDTH;
				}
			}

			Bitmap orgBitmap = Bitmap.createBitmap(SIDEVIEW_BITMAP_WIDTH, SIDEVIEW_BITMAP_HEIGHT, Bitmap.Config.ARGB_8888);
			orgBitmap.copyPixelsFromBuffer(IntBuffer.wrap(mBitmapData));

			Matrix updownInversion = new Matrix();
			updownInversion.setScale(1, -1);
			Bitmap updownInversionBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, orgBitmap.getWidth(), orgBitmap.getHeight(), updownInversion, false);
			orgBitmap.recycle();

			mBitmap = Bitmap.createScaledBitmap(updownInversionBitmap, SIDEVIEW_SCALE*SIDEVIEW_WIDTH, SIDEVIEW_SCALE*SIDEVIEW_HEIGHT, false);
			updownInversionBitmap.recycle();

			invalidate();
		}
	}

	private void init() {
		Arrays.fill(mLineZero, 0);

		mRectSideview = new Rect(0, 0, SIDEVIEW_WIDTH+2*SIDEVIEW_MARGIN, SIDEVIEW_HEIGHT+2*SIDEVIEW_MARGIN);
		mPaint = new Paint();
		mPaint.setColor(Color.BLUE);
		mPaintRed = new Paint();
		mPaintRed.setColor(Color.RED);
		mPaintRed.setStrokeWidth(4);
	}
}
